package myJs.cps.myTable

import myJs.Implicits._
import myJs.cps.BootstrapTableCp.Column
import myJs.cps.{Display, Style}
import myJs.myPkg.i18n.ReactI18next
import myJs.myPkg.jquery.$
import myJs.tool.Pojo._
import org.scalajs.dom.{Event, document}
import org.scalajs.dom.html.Button
import slinky.core.{FunctionalComponent, SyntheticEvent, TagElement}
import slinky.core.annotations.react
import slinky.web.html._

import scala.collection.immutable.SeqMap
import scala.scalajs.js

/**
 * Created by yz on 21/1/2022
 */
@react object FilterButtonCp {

  case class Props(column: Column,
                   sortField: String, sortFieldChange: String => Unit,
                   order: String, orderChange: String => Unit,
                   menuShow: Boolean, menuShowChange: Boolean => Unit,
                   menuField: String, menuFieldChange: String => Unit,
                   tmpSearchMap: SeqMap[String, SearchData],
                   tmpSearchMapChange: SeqMap[String, SearchData] => Unit,
                   confirmFilter: String => () => Unit
                  )

  val component = FunctionalComponent[Props] { props =>

    val js.Tuple3(t, i18n, _) = ReactI18next.useTranslation()

    object FTool {

      def endDateChange(curField: String) = (v: String) => {
        val curSearchMap = props.tmpSearchMap.updatedWith(curField) { op =>
          op.map { searchData =>
            searchData.asInstanceOf[DateSearchData].copy(endDate = v)
          }
        }
        props.tmpSearchMapChange(curSearchMap)
      }

      def maxChange(curField: String) = (v: String) => {
        val curSearchMap = props.tmpSearchMap.updatedWith(curField) { op =>
          op.map { searchData =>
            searchData.asInstanceOf[NumericSearchData].copy(max = v)
          }
        }
        props.tmpSearchMapChange(curSearchMap)
      }

      def startDateChange(curField: String) = (v: String) => {
        val curSearchMap = props.tmpSearchMap.updatedWith(curField) { op =>
          op.map { searchData =>
            searchData.asInstanceOf[DateSearchData].copy(startDate = v)
          }
        }
        props.tmpSearchMapChange(curSearchMap)
      }

      def minChange(curField: String) = (v: String) => {
        val curSearchMap = props.tmpSearchMap.updatedWith(curField) { op =>
          op.map { searchData =>
            searchData.asInstanceOf[NumericSearchData].copy(min = v)
          }
        }
        props.tmpSearchMapChange(curSearchMap)
      }

      def valuesChange(curField: String) = (v: List[String]) => {
        val curSearchMap = props.tmpSearchMap.updatedWith(curField) { op =>
          op.map { searchData =>
            searchData.asInstanceOf[CheckboxSearchData].copy(values = v)
          }
        }
        props.tmpSearchMapChange(curSearchMap)
      }

      def menuShowF(curField: String) = (e: SyntheticEvent[TagElement#RefType, Event]) => {
        val buttonJq = $(e.target.asInstanceOf[Button])
        val yTotalLeft = buttonJq.offset().left
        val width = 210
        val pageWidth = document.body.clientWidth
        val trueYLeft = if (yTotalLeft + width > pageWidth) pageWidth - 220 - 6 - yTotalLeft else 0
        val ulJq = buttonJq.parent().find("ul")
        ulJq.css("left", s"${trueYLeft}px")
        props.menuShowChange(true)
        props.menuFieldChange(curField)
      }

      def execSort(curSortField: String, curOrder: String) = () => {
        props.sortFieldChange(curSortField)
        props.orderChange(curOrder)
        props.menuShowChange(false)
      }

      def searchTypeChange(curField: String) = (v: String) => {
        val curSearchMap = props.tmpSearchMap.updatedWith(curField) { op =>
          op.map { searchData =>
            searchData.asInstanceOf[TextSearchData].copy(searchType = v)
          }
        }
        props.tmpSearchMapChange(curSearchMap)
      }

      def textChange(curField: String) = (v: String) => {
        val curSearchMap = props.tmpSearchMap.updatedWith(curField) { op =>
          op.map { x =>
            x.asInstanceOf[TextSearchData].copy(text = v)
          }
        }
        props.tmpSearchMapChange(curSearchMap)
      }

      def hideMenu = () => {
        props.menuShowChange(false)
      }

    }

    val column = props.column
    val sortField = props.sortField
    val order = props.order
    val menuShow = props.menuShow
    val menuField = props.menuField
    val tmpSearchMap = props.tmpSearchMap
    if (column.operable && tmpSearchMap.isDefinedAt(column.field)) {
      val isAscActive = (column.field == sortField && order == "asc")
      val isDescActive = (column.field == sortField && order == "desc")
      val sortFa = if (isAscActive) {
        "fa-long-arrow-up"
      } else if (isDescActive) {
        "fa-long-arrow-down"
      } else ""
      val ulShow = if (menuShow && menuField == column.field) Display.block else Display.none
      val searchData = tmpSearchMap(column.field)
      val isNumeric = searchData match {
        case NumericSearchData(min, max, kind) => true
        case _ => false
      }
      div(className := "myFilterButton", style := Style(float = "right", position = "relative", marginLeft = 2),
        button(className := "btn btn-default dropdown-toggle myButton",
          data - "toggle" := "dropdown", style := Style(display = Display.`inline-block`),
          onClick := FTool.menuShowF(column.field),
          span(className := "caret"),
          i(className := s"fa ${sortFa}"),
        ),
        ul(className := "my-dropdown-menu menuContent filterContent", style := STool.ul(ulShow),
          form(className := "form-horizontal myForm", style := Style(marginBottom = 10),
            AscLiCp(onClickF = FTool.execSort(column.field, "asc"), isActive = isAscActive,
              isNumeric = isNumeric),
            DescLiCp(onClickF = FTool.execSort(column.field, "desc"), isActive = isDescActive,
              isNumeric = isNumeric),
            li(className := "myDivider"),
            searchData match {
              case DateSearchData(startDate, endDate) =>
                DateSearchLiCp(startDate = startDate,
                  startDateChange = FTool.startDateChange(column.field),
                  endDate = endDate, endDateChange = FTool.endDateChange(column.field))
              case TextSearchData(searchType, text) =>
                TextSearchLiCp(searchType = searchType,
                  searchTypeChange = FTool.searchTypeChange(column.field),
                  text = text, textChange = FTool.textChange(column.field))
              case NumericSearchData(min, max, kind) =>
                NumericSearchLiCp(min = min,
                  minChange = FTool.minChange(column.field),
                  max = max, maxChange = FTool.maxChange(column.field))
              case CheckboxSearchData(values) =>
                CheckboxSearchLiCp(values = values,
                  valuesChange = FTool.valuesChange(column.field),
                  optionMap = column.optionMap)

            }
          ),
          div(className := "modal-footer bg-info",
            button(className := "btn btn-sm blue",
              onClick := props.confirmFilter(column.field), s"${t("confirm")}"),
            button(`type` := "button", className := "btn btn-default myHide",
              s"${t("close")}", onClick := FTool.hideMenu)
          )


        )
      )

    } else null

  }

  object STool {

    def ul(ulShow: Display) = {
      Style(marginTop = 0,
        background = "#F8F8F8", border = "1px solid #c5c5c5", borderRadius = 0, fontWeight = 400,
        paddingTop = 0, paddingBottom = 0, width = 212,
        boxShadow = "1px 2px 3px rgba(0, 0, 0, .5)", display = ulShow)
    }

  }

}
